I've created a custom datatype but the save Method doens't always work. When I press the save button the value is saved, but when I press the save and publish button it saves the value just once. When I change the value again and save it the value isn't being saved anymore. So after the save and publish button is pressed neither the save or save and publish button work anymore. Here is my save code:
[code]
public void Save()
{
this._data.Value = _tribalDatepicker.Text;
}
[/code]
When I debug the _tribalDatepicker.Text is always the value I typed in the textbox, but after the save and publish button the value in _tribalDatepicker.Text is the previous value and not the value I typed in. Is this an Umbraco bug or does anybody know how this can be solved?
Never had issues with Custom Datatypes, but when you add a Breakpoint on the Save Method? Is that Breakpoint Hit every time.
Cheers,
Richard[/quote]
Yes the breakpoint is hit every time, but sometimes the value of _tribalDatepicker.Text is not the value I entered in the textbox, but the pervious saved value.
Can it be that something else is updating the Value? I haven't experience any of these problems so maybe it's popssible to submit the full source of the code to the forum and people can look at it for you?
[quote=rsoeteman]Can it be that something else is updating the Value? I haven't experience any of these problems so maybe it's popssible to submit the full source of the code to the forum and people can look at it for you?
Cheers,
Richard[/quote]
Here is the source code:
UmbdtDatepicker.cs
[code]
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml;
using umbraco.DataLayer;
using umbraco.BusinessLogic;
using umbraco.editorControls;
using umbraco.controls;
using TribalControls;
namespace TribalUmbraco.DataTypes
{
public class UmbdtDatepicker: umbraco.cms.businesslogic.datatype.BaseDataType, umbraco.interfaces.IDataType
{
private umbraco.interfaces.IDataEditor Editor;
private umbraco.interfaces.IData _baseData;
private UmbdtDatepickerPrevalueEditor _prevalueeditor;
public override umbraco.interfaces.IDataEditor DataEditor
{
get
{
if (Editor == null) Editor = new UmbdtDatepickerDataEditor(Data);
return _Editor;
}
}
public override umbraco.interfaces.IData Data
{
get
{
if (baseData == null) baseData = new umbraco.cms.businesslogic.datatype.DefaultData(this);
return _baseData;
}
}
public override Guid Id
{
get {
return new Guid("bfeb08d3-1db9-4e83-85b6-3de5c828d52e");
}
}
public override string DataTypeName
{
get
{
return "[Tribal] Datepicker";
}
}
public override umbraco.interfaces.IDataPrevalue PrevalueEditor
{
get
{
if (prevalueeditor == null) prevalueeditor = new UmbdtDatepickerPrevalueEditor(this);
return _prevalueeditor;
}
}
}
// This class will define/render/load/save the datatype settings
public class UmbdtDatepickerPrevalueEditor : System.Web.UI.WebControls.PlaceHolder, umbraco.interfaces.IDataPrevalue
{
#region IDataPrevalue Members
tribalDatepicker = new TribalDatepicker();
_tribalDatepicker.ID = ControlId("DpCurrentDatePicker");
_tribalDatepicker.TribalDateTime = DateTime.Today;
// set selected value if data was saved before
if (!String.IsNullOrEmpty(data.Value.ToString()))
{ tribalDatepicker.TribalDateTime = Convert.ToDateTime(data.Value);
}
//// add datatype value controls to data editor
base.ContentTemplateContainer.Controls.Add(tribalDatepicker);
}
}
}
[/code]
TribalDatepicker.cs
[code]
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Collections;
using System.Collections.Specialized;
using System.Globalization;
using umbraco;
public string CustomMinutes
{
set { _minutes = value.Split(", ".ToCharArray()); }
}
public bool EmptyDateAsDefault
{
set { _emptyDateAsDefault = value; }
}
public bool ShowTime
{
set { _showTime = value; }
get { return _showTime; }
}
public string GlobalizationAlias
{
set { _globalAlias = value; }
get { return _globalAlias; }
}
///
/// Bepaald de tijd die getoond wordt in de textbox.
///
[Bindable(true),
Category("Appearance"),
DefaultValue("")]
public DateTime TribalDateTime
{
get
{
return _datetime;
}
///
/// Als een datum ongeldig is wordt deze op false gezet zodat een foutmelding getoond wordt.
///
public bool DatetimeNotValid
{
get
{
return _datetimeNotValid;
}
set
{
_datetimeNotValid = value;
}
}
protected override void OnInit(EventArgs e)
{
if (this.ShowTime)
{
dateFormatJs += " %H:%M";
dateFormatNet += " HH:mm";
dateFormatJsSelect = ",\n" +
" showsTime : true,\n" +
" timeFormat : 24 \n";
}
//Voeg al het javascript toe aan de pagina.
Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), "datepickerWithPopup", "
///
/// Render this control to the output parameter specified.
///
/// The HTML writer to write out to
protected override void Render(HtmlTextWriter output)
{
//Toon de textbox met de kalender erachter.
base.Render(output);
output.WriteLine("");
if (DatetimeNotValid)
{
output.WriteLine("De datum was ongeldig en is daarom terug gezet op vandaag.");
}
if (!Page.IsPostBack)
{ tribalDatepicker = new TribalDatepicker();
_tribalDatepicker.ID = ControlId("DpCurrentDatePicker");
_tribalDatepicker.TribalDateTime = DateTime.Today;
// set selected value if data was saved before
if (!String.IsNullOrEmpty(data.Value.ToString()))
{ tribalDatepicker.TribalDateTime = Convert.ToDateTime(data.Value);
}
//// add datatype value controls to data editor
base.ContentTemplateContainer.Controls.Add(_tribalDatepicker);
}
}
[/code]
The reason you get the error is beacuse you need to recreate the object again in the OnInit Method. The only thing that you can surround with Page.IsPostBack is setting of the Date Value.
if (!Page.IsPostBack)
{
_tribalDatepicker.TribalDateTime = DateTime.Today;
// set selected value if data was saved before
if (!String.IsNullOrEmpty(data.Value.ToString()))
{ tribalDatepicker.TribalDateTime = Convert.ToDateTime(data.Value);
}
}
//// add datatype value controls to data editor
base.ContentTemplateContainer.Controls.Add(_tribalDatepicker);
}
[/code]
I've also peaked at the code that you submitted and I see one Catch block that doesn't do anything when setting the TribalDatTime Value. Maybe set a breakpoint there?
[code]public DateTime TribalDateTime
{
get
{
return _datetime;
}
if (!Page.IsPostBack)
{
// set selected value if data was saved before
if (!String.IsNullOrEmpty(data.Value.ToString()))
{
_tribalDatepicker.TribalDateTime = Convert.ToDateTime(data.Value);
}
}
//// add datatype value controls to data editor
base.ContentTemplateContainer.Controls.Add(_tribalDatepicker);
}
}
[/code]
Custom datatype save problem [SOLVED]
Hello,
I've created a custom datatype but the save Method doens't always work. When I press the save button the value is saved, but when I press the save and publish button it saves the value just once. When I change the value again and save it the value isn't being saved anymore. So after the save and publish button is pressed neither the save or save and publish button work anymore. Here is my save code:
[code]
public void Save()
{
this._data.Value = _tribalDatepicker.Text;
}
[/code]
When I debug the _tribalDatepicker.Text is always the value I typed in the textbox, but after the save and publish button the value in _tribalDatepicker.Text is the previous value and not the value I typed in. Is this an Umbraco bug or does anybody know how this can be solved?
Hi,
Never had issues with Custom Datatypes, but when you add a Breakpoint on the Save Method? Is that Breakpoint Hit every time.
Cheers,
Richard
[quote=rsoeteman]Hi,
Never had issues with Custom Datatypes, but when you add a Breakpoint on the Save Method? Is that Breakpoint Hit every time.
Cheers,
Richard[/quote]
Yes the breakpoint is hit every time, but sometimes the value of _tribalDatepicker.Text is not the value I entered in the textbox, but the pervious saved value.
Can it be that something else is updating the Value? I haven't experience any of these problems so maybe it's popssible to submit the full source of the code to the forum and people can look at it for you?
Cheers,
Richard
[quote=rsoeteman]Can it be that something else is updating the Value? I haven't experience any of these problems so maybe it's popssible to submit the full source of the code to the forum and people can look at it for you?
Cheers,
Richard[/quote]
Here is the source code:
UmbdtDatepicker.cs
[code]
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml;
using umbraco.DataLayer;
using umbraco.BusinessLogic;
using umbraco.editorControls;
using umbraco.controls;
using TribalControls;
namespace TribalUmbraco.DataTypes
{
public class UmbdtDatepicker: umbraco.cms.businesslogic.datatype.BaseDataType, umbraco.interfaces.IDataType
{
private umbraco.interfaces.IDataEditor Editor;
private umbraco.interfaces.IData _baseData;
private UmbdtDatepickerPrevalueEditor _prevalueeditor;
public override umbraco.interfaces.IDataEditor DataEditor
{
get
{
if (Editor == null)
Editor = new UmbdtDatepickerDataEditor(Data);
return _Editor;
}
}
public override umbraco.interfaces.IData Data
{
get
{
if (baseData == null)
baseData = new umbraco.cms.businesslogic.datatype.DefaultData(this);
return _baseData;
}
}
public override Guid Id
{
get {
return new Guid("bfeb08d3-1db9-4e83-85b6-3de5c828d52e");
}
}
public override string DataTypeName
{
get
{
return "[Tribal] Datepicker";
}
}
public override umbraco.interfaces.IDataPrevalue PrevalueEditor
{
get
{
if (prevalueeditor == null)
prevalueeditor = new UmbdtDatepickerPrevalueEditor(this);
return _prevalueeditor;
}
}
}
// This class will define/render/load/save the datatype settings
public class UmbdtDatepickerPrevalueEditor : System.Web.UI.WebControls.PlaceHolder, umbraco.interfaces.IDataPrevalue
{
#region IDataPrevalue Members
// referenced datatype
private umbraco.cms.businesslogic.datatype.BaseDataType _datatype;
// constructor
public UmbdtDatepickerPrevalueEditor (umbraco.cms.businesslogic.datatype.BaseDataType DataType)
{
_datatype = DataType;
}
public Control Editor
{
get
{
return this;
}
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
}
public void Save()
{
}
#endregion
public static ISqlHelper SqlHelper
{
get
{
return Application.SqlHelper;
}
}
}
public class UmbdtDatepickerDataEditor : System.Web.UI.UpdatePanel, umbraco.interfaces.IDataEditor
{
private umbraco.interfaces.IData _data;
// datatype DataEditor controls
private TribalDatepicker _tribalDatepicker;
public UmbdtDatepickerDataEditor(umbraco.interfaces.IData Data)
{
_data = Data;
}
public virtual bool TreatAsRichTextEditor
{
get { return false; }
}
public bool ShowLabel
{
get { return true; }
}
public Control Editor
{
get { return this; }
}
public void Save()
{
DateTime newDate;
if (DateTime.TryParse(tribalDatepicker.Text, out newDate))
{
this.data.Value = _tribalDatepicker.Text;
_tribalDatepicker.DatetimeNotValid = false;
}
else
{
this.data.Value = string.Format("{0:yyyy-MM-dd}", DateTime.Today);
tribalDatepicker.TribalDateTime = DateTime.Today;
_tribalDatepicker.DatetimeNotValid = true;
}
}
public string ControlId(string name)
{
return string.Concat(name, ((umbraco.cms.businesslogic.datatype.DefaultData)data).PropertyId.ToString());
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
tribalDatepicker = new TribalDatepicker();
_tribalDatepicker.ID = ControlId("DpCurrentDatePicker");
_tribalDatepicker.TribalDateTime = DateTime.Today;
// set selected value if data was saved before
if (!String.IsNullOrEmpty(data.Value.ToString()))
{
tribalDatepicker.TribalDateTime = Convert.ToDateTime(data.Value);
}
//// add datatype value controls to data editor
base.ContentTemplateContainer.Controls.Add(tribalDatepicker);
}
}
}
[/code]
TribalDatepicker.cs
[code]
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Collections;
using System.Collections.Specialized;
using System.Globalization;
using umbraco;
namespace TribalControls
{
///
/// Summary description for datePicker.
///
[DefaultProperty("Text"),
ToolboxData("<{0}:datePicker runat=server>")]
public class TribalDatepicker : TextBox
{
private DateTime _datetime;
private bool _showTime = false;
private bool _emptyDateAsDefault = false;
private bool _datetimeNotValid = false;
private string[] _minutes = { "00", "15", "30", "45" };
private string[] _hours = { "--", "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23" };
private string[] _days = { "--", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31" };
private ArrayList _months = new ArrayList();
private ArrayList _years = new ArrayList();
private string _globalAlias = "nl-NL";
private string dateFormatJs = "%Y-%m-%d";
private string dateFormatNet = "yyyy-MM-dd";
private string dateFormatJsSelect = "";
public string CustomMinutes
{
set { _minutes = value.Split(", ".ToCharArray()); }
}
public bool EmptyDateAsDefault
{
set { _emptyDateAsDefault = value; }
}
public bool ShowTime
{
set { _showTime = value; }
get { return _showTime; }
}
public string GlobalizationAlias
{
set { _globalAlias = value; }
get { return _globalAlias; }
}
///
/// Bepaald de tijd die getoond wordt in de textbox.
///
[Bindable(true),
Category("Appearance"),
DefaultValue("")]
public DateTime TribalDateTime
{
get
{
return _datetime;
}
set
{
try
{
_datetime = value;
this.Text = string.Format("{0:yyyy-MM-dd}", _datetime);
}
catch
{
}
}
}
///
/// Als een datum ongeldig is wordt deze op false gezet zodat een foutmelding getoond wordt.
///
public bool DatetimeNotValid
{
get
{
return _datetimeNotValid;
}
set
{
_datetimeNotValid = value;
}
}
protected override void OnInit(EventArgs e)
{
if (this.ShowTime)
{
dateFormatJs += " %H:%M";
dateFormatNet += " HH:mm";
dateFormatJsSelect = ",\n" +
" showsTime : true,\n" +
" timeFormat : 24 \n";
}
//Voeg al het javascript toe aan de pagina.
Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), "datepickerWithPopup", " ");
Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), "datepickerWithPopupHelper", " ");
Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), "datepickerWithPopupLang", " ");
Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), "datepickerWithPopSkin", "");
base.OnInit(e);
}
///
/// Render this control to the output parameter specified.
///
/// The HTML writer to write out to
protected override void Render(HtmlTextWriter output)
{
//Toon de textbox met de kalender erachter.
base.Render(output);
output.WriteLine("");
if (DatetimeNotValid)
{
output.WriteLine("De datum was ongeldig en is daarom terug gezet op vandaag.");
}
string strSetup = " Calendar.setup({" +
" inputField : \"" + this.ClientID + "\",\n" +
" ifFormat : \"" + dateFormatJs + "\",\n" +
" displayArea : \"" + this.ClientID + "showe\",\n" +
" daFormat : \"" + dateFormatJs + "\",\n" +
" button : \"" + this.ClientID + "ftriggere\",\n" +
" singleClick : true\n" +
dateFormatJsSelect +
" });";
try
{
if (ScriptManager.GetCurrent(Page).IsInAsyncPostBack)
ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "Calendar.Setup" + this.ClientID, strSetup, true);
else
Page.ClientScript.RegisterStartupScript(this.GetType(), "Calendar.Setup" + this.ClientID, strSetup, true);
}
catch
{
Page.ClientScript.RegisterStartupScript(this.GetType(), "Calendar.Setup" + this.ClientID, strSetup, true);
}
}
private string markMinute(int minute)
{
int _currentDiff = 100;
int _currentMinute = 0;
System.Collections.ArrayList _localMinutes = new ArrayList();
foreach (string s in _minutes)
{
_localMinutes.Add(s);
}
_localMinutes.Add("60");
foreach (string s in _localMinutes)
{
if (s.Trim() != "")
{
if (currentDiff > Math.Abs(int.Parse(s) - minute))
{
currentMinute = int.Parse(s);
_currentDiff = Math.Abs(int.Parse(s) - minute);
}
}
}
if (currentMinute == 60)
return "00";
else
{
if (_currentMinute.ToString().Length == 1)
return "0" + _currentMinute.ToString();
else
return _currentMinute.ToString();
}
}
}
}
[/code]
The TribalDatapicker.cs is an adapted version of the datePicker I found in the Umbraco Source code.
Could it be OnInit on your DataEditor that sets the value before it gets saved?
Just a thought, try surrounding it with a if(!IsPostBack)
Edit: Maybe that's not needed anyway...
[quote=fed]Could it be OnInit on your DataEditor that sets the value before it gets saved?
Just a thought, try surrounding it with a if(!IsPostBack)
Edit: Maybe that's not needed anyway...[/quote]
I tried surrounding it with a if(!IsPostBack), but then I get an "object reference not set to an instance of an object" error when I try to save.
[code]
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (!Page.IsPostBack)
{
tribalDatepicker = new TribalDatepicker();
_tribalDatepicker.ID = ControlId("DpCurrentDatePicker");
_tribalDatepicker.TribalDateTime = DateTime.Today;
// set selected value if data was saved before
if (!String.IsNullOrEmpty(data.Value.ToString()))
{
tribalDatepicker.TribalDateTime = Convert.ToDateTime(data.Value);
}
//// add datatype value controls to data editor
base.ContentTemplateContainer.Controls.Add(_tribalDatepicker);
}
}
[/code]
Why it's not needed anyway?
Hi,
The reason you get the error is beacuse you need to recreate the object again in the OnInit Method. The only thing that you can surround with Page.IsPostBack is setting of the Date Value.
[code]
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
tribalDatepicker = new TribalDatepicker();
_tribalDatepicker.ID = ControlId("DpCurrentDatePicker");
if (!Page.IsPostBack)
{
_tribalDatepicker.TribalDateTime = DateTime.Today;
// set selected value if data was saved before
if (!String.IsNullOrEmpty(data.Value.ToString()))
{
tribalDatepicker.TribalDateTime = Convert.ToDateTime(data.Value);
}
}
//// add datatype value controls to data editor
base.ContentTemplateContainer.Controls.Add(_tribalDatepicker);
}
[/code]
I've also peaked at the code that you submitted and I see one Catch block that doesn't do anything when setting the TribalDatTime Value. Maybe set a breakpoint there?
[code]public DateTime TribalDateTime
{
get
{
return _datetime;
}
set
{
try
{
_datetime = value;
this.Text = string.Format("{0:yyyy-MM-dd}", _datetime);
}
catch
{
}
}
[/code]
Thank you Richard! Everything is working now.
Here is my code.
[code]
public class UmbdtDatepickerDataEditor : System.Web.UI.UpdatePanel, umbraco.interfaces.IDataEditor
{
private umbraco.interfaces.IData data;
// datatype DataEditor controls
private TribalDatepicker _tribalDatepicker;
public UmbdtDatepickerDataEditor(umbraco.interfaces.IData Data)
{
_data = Data;
_tribalDatepicker = new TribalDatepicker();
_tribalDatepicker.ID = ControlId("DpCurrentDatePicker");
_tribalDatepicker.TribalDateTime = DateTime.Today;
}
public virtual bool TreatAsRichTextEditor
{
get { return false; }
}
public bool ShowLabel
{
get { return true; }
}
public Control Editor
{
get { return this; }
}
public void Save()
{
DateTime newDate;
if (DateTime.TryParse(tribalDatepicker.Text, out newDate))
{
this.data.Value = _tribalDatepicker.Text;
_tribalDatepicker.DatetimeNotValid = false;
}
else
{
this.data.Value = string.Format("{0:yyyy-MM-dd}", DateTime.Today);
tribalDatepicker.TribalDateTime = DateTime.Today;
_tribalDatepicker.DatetimeNotValid = true;
}
}
public string ControlId(string name)
{
return string.Concat(name, ((umbraco.cms.businesslogic.datatype.DefaultData)data).PropertyId.ToString());
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (!Page.IsPostBack)
{
// set selected value if data was saved before
if (!String.IsNullOrEmpty(data.Value.ToString()))
{
_tribalDatepicker.TribalDateTime = Convert.ToDateTime(data.Value);
}
}
//// add datatype value controls to data editor
base.ContentTemplateContainer.Controls.Add(_tribalDatepicker);
}
}
[/code]
is working on a reply...